// ExtractorApi.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "ExtractorApi.h"

#include <map>
#include <vector>
#include <string>

using namespace std;


#include <windows.h>

//extern "C" {
#include "extr_api.h"
//};

#include <mshtml.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;




class KeyPhraseItem{

public:

	long Index;
	string Phrase;
	int Frequency;
	KeyPhraseItem():Index(0) , Frequency(0){};
	KeyPhraseItem(int LcIndex,string lcPhrase): Index(LcIndex) , Frequency(0) , Phrase (lcPhrase){}
};

bool operator<(KeyPhraseItem First  , KeyPhraseItem Second )
{
	return ( First < Second );
}

typedef map< string , KeyPhraseItem> KeyPhraseMap;

class KeyPhraseCollection
{

private:
	
	KeyPhraseMap MyKeyPhrases;
	int AddKeyPhraseItem;
};

class FeatureItem{

public:

	long Index;
	double Weight;
	int Frequency;
	FeatureItem():Index(0) , Weight(0) , Frequency(0){};
	FeatureItem( int LcIndex , double LcWeight ) : Index(LcIndex) , Weight(LcWeight) , Frequency(0){}
};


typedef vector<FeatureItem> FeatureItemVector


class HtmlPage
{

public:
	
	FeatureItemVector MyFeatures;
	bool GenerateTermsList(char* stream);
};

typedef vector<HtmlPage> HtmlPageVector;



HtmlPageVector AllPagesVector;

KeyPhrase PhrasesTree;
vector<KeyPhrase> PhrasesVector;
int NumOfPhrases;



typedef vector<string> strVecFilesContent;
typedef vector<string> strVecFilesNames;

int SearchDirectory(strVecFilesNames &refvecFiles,
                    const string   &refcstrRootDirectory,
                    const string   &refcstrExtension)
{
  string          strFilePath;             // Filepath
  string          strPattern;              // Pattern
  HANDLE          hFile;                   // Handle to file
  WIN32_FIND_DATA FileInformation;         // File information


  strPattern = refcstrRootDirectory + "\\*." + refcstrExtension;

  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    do
    {
      if(FileInformation.cFileName[0] != '.')
      {
        strFilePath.erase();
        strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

        if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
          // Search subdirectory
          int iRC = SearchDirectory(refvecFiles, strFilePath, refcstrExtension);
          if(iRC)
            return iRC;
        }
        else
        {
          // Save filename
          refvecFiles.push_back(strFilePath);
        }
      }
    } while(::FindNextFile(hFile, &FileInformation) == TRUE);

    // Close handle
    ::FindClose(hFile);

    DWORD dwError = ::GetLastError();
    if(dwError != ERROR_NO_MORE_FILES)
      return dwError;
  }

  return 0;
}

bool HtmlPage::GenerateTermsList(char* stream)
{
	bool allWentWell = true ;
	
	int    LanguageID    = 0;

	int    OutCharCodeID = 0;
	double DesiredNumber = 30;

	void  *StopMemory;
	void  *DocumentMemory;

	int    PhraseListSize;
	int    PhraseIndex;
	char  *Phrase;
	double Score;

	int    ErrorCode;
	char  *ErrorMessage;
	
	char   num_phrase_string[IN_LEN];
	string strPhrase;
	int  Result=0;
	FeatureItem *pFeatureItem=NULL;

	ErrorCode = ExtrCreateStopMemory(&StopMemory);
	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	       	//AddToLog (5, ErrorMessage);
		return false ;
	}

	ErrorCode = ExtrCreateDocumentMemory(&DocumentMemory);

	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	        //AddToLog (5, ErrorMessage);
		return false ;
	}

	ErrorCode = ExtrActivateHTMLFilter(DocumentMemory, StopMemory);

    	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	        //AddToLog (5, ErrorMessage);
		return false ;
    	}


	strcpy (num_phrase_string,"30") ; // maximum is 30

	num_phrase_string[strcspn(num_phrase_string, "\n\r")] = '\0';

	if (num_phrase_string[0] == '\0') {
	       //AddToLog (6, "\nThe desired number of phrases is set to seven (7). \n"); 
	} else {

		ErrorCode = ExtrSetNumberPhrases(DocumentMemory, DesiredNumber);
		if (ErrorCode > 0) {
			ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
		    	//AddToLog (5, ErrorMessage);
			return false ;
	    }
	}

    	OutCharCodeID = ENC_DOS;
    	ErrorCode = ExtrSetOutputCode(DocumentMemory, OutCharCodeID);
    	if (ErrorCode > 0) {
        	ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
          	//AddToLog (5, ErrorMessage);
          	return false ;
    	}

	string m_strHTMLBody;
   	ErrorCode = ExtrReadDocumentBuffer(DocumentMemory, StopMemory,
                        (void *) stream, strlen(stream));
   	if (ErrorCode > 0) {
   		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
   		//AddToLog (5, ErrorMessage);
   		return false ;
   	}

	ErrorCode = ExtrSignalDocumentEnd(DocumentMemory, StopMemory);

	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	      	//AddToLog (5, ErrorMessage);
		return false ;
	}

	ErrorCode = ExtrGetDocumentLanguage(DocumentMemory, &LanguageID);

	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	       	//AddToLog (5, ErrorMessage);
		return false ;
	}

	ErrorCode = ExtrGetPhraseListSize(DocumentMemory, &PhraseListSize);

	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
		//AddToLog (5, ErrorMessage);
		return false ;
	}

	if (PhraseListSize == 0) {
	       //AddToLog (3, "\nNo keyphrases were extracted! \n\n");
	}

	if (PhraseListSize > 0) {
	    for (PhraseIndex = 0; PhraseIndex < PhraseListSize; PhraseIndex++) 
		{
			ErrorCode = ExtrGetPhraseByIndex(DocumentMemory, PhraseIndex,
									        (void **) &Phrase);

			
			strPhrase.assign(Phrase);
			
			 
			if (ErrorCode > 0) {
				ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
				//AddToLog (5, ErrorMessage);
				return false ;
			}
			ErrorCode = ExtrGetScoreByIndex(DocumentMemory, PhraseIndex, &Score);

			Result=AddKeyPhrase( strPhrase );
			pFeatureItem=new FeatureItem(Result , Score );
			MyFeatures.insert(FeatureItemMap::value_type(Result,*pFeatureItem));
			delete pFeatureItem;
			if (ErrorCode > 0) {
				ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
		       		//AddToLog (5, ErrorMessage);
				return false ;
			}
	//		cout<<PhraseIndex<<" "<<Phrase<<" "<<Score<<endl;
	//		m_lstPageTMyTerms->Add(new TMyTerm(Phrase,Score)) ;

		}
	}

	ErrorCode = ExtrClearDocumentMemory(DocumentMemory);
	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	       	//AddToLog (5, ErrorMessage);
		return false ;
	}

	ErrorCode = ExtrClearStopMemory(StopMemory);
	if (ErrorCode > 0) {
		ExtrGetErrorMessage(ErrorCode, &ErrorMessage);
	       	//AddToLog (5, ErrorMessage);
		return false ;
	}

	return allWentWell ;
}

string ReadFile(string FilePath)
{
	FILE *fp;
	string Stream;
	char w[2];
	w[1]='\0';
	fp=fopen( FilePath.c_str() , "r" );
	while( (fscanf(fp,"%c",&w[0])) != EOF )
		Stream.append(w,1);
	fclose(fp);
	return Stream;
}




int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0 , iRC;
	char *p;
	int DirOpen;
	strVecFilesNames FilesNames;
	strVecFilesContent FilesContent;
	NumOfPhrases=1;
	HtmlPage *pHtmlPage=NULL;
	char DirPath[300];
	DirPath[0]='\0';
	strVecFilesContent::iterator posFilesContent;
	strVecFilesNames::iterator posFilesNames;
	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		cout<<"please enter the web page's directory path\n";
		//cin>>DirPath;
		strcpy( DirPath , "E:\\Extractor\\ExtractorApiFileInMemory\\HtmlFiles" );
		iRC = SearchDirectory(FilesNames, DirPath , "html");//read html files
		iRC = SearchDirectory(FilesNames, DirPath, "htm" );//read htm files
		for ( posFilesNames = FilesNames.begin() ; posFilesNames != FilesNames.end() ; posFilesNames++ )
			FilesContent.push_back( ReadFile( posFilesNames->c_str() ) );
		for ( posFilesContent = FilesContent.begin() ; posFilesContent != FilesContent.end() ; posFilesContent++ )
		{
			pHtmlPage=new HtmlPage;			
			pHtmlPage->GenerateTermsList((char*) *posFilesContent->c_str() );			
		}
		cout<<"\nFinito La comd";
	}
	return nRetCode;
}


